<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// $Id: ThinkException.class.php 2791 2012-02-29 10:08:57Z liu21st $
/**
 +------------------------------------------------------------------------------
 * ThinkPHP系统异常基类
 +------------------------------------------------------------------------------
 * @category   Think
 * @package  Think
 * @subpackage  Exception
 * @author    liu21st <liu21st@gmail.com>
 * @version   $Id: ThinkException.class.php 2791 2012-02-29 10:08:57Z liu21st $
 * @last modify 2012-6-13 16:14:12 by mashanling
 +------------------------------------------------------------------------------
 */
class ThinkException extends Exception {
    /**
     +----------------------------------------------------------
     * 异常类型
     +----------------------------------------------------------
     * @var string
     * @access private
     +----------------------------------------------------------
     */
    private $type;
    // 是否存在多余调试信息
    private $extra;

    /**
     +----------------------------------------------------------
     * 架构函数
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $message  异常信息
     +----------------------------------------------------------
     */
    public function __construct($message, $code = 0, $extra = false) {
        parent::__construct($message, $code);
        $this->type  = get_class($this);
        $this->extra = $extra;
    }

    /**
     +----------------------------------------------------------
     * 异常输出 所有异常处理类均通过__toString方法输出错误
     * 每次异常都会写入系统日志
     * 该方法可以被子类重载
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @return array
     +----------------------------------------------------------
     */
    public function __toString() {
        $trace      = $this->getTrace();

        if ($this->extra) {//通过throw_exception抛出的异常要去掉多余的调试信息
            //$shift = array_shift($trace);
            //$trace[0]['class'] = $trace[1]['class'];
            //$trace[0]['type']  = $trace[1]['type'];
            $trace[1]['file']  = isset($trace[1]['file']) ? $trace[1]['file'] : $trace[0]['file'];
            $trace[1]['line']  = isset($trace[1]['line']) ? $trace[1]['line'] : 'unknow';
        }
        else {
            $trace[0]['file'] = $this->file;
            $trace[0]['line'] = $this->line;
        }

        $shift = $trace[0];
        //$this->class     = $shift['class'];
        $this->function  = $shift['function'];
        $this->file      = $shift['file'];
        $this->line      = $shift['line'];
        $file            = file($this->file);


        $time       = local_date();
        $trace_info = '';

        foreach ($trace as $t) {
            $trace_info .= '[' . $time . '] ';
            $trace_info .=  isset($t['file']) ?  $t['file'] . ' (' . $t['line'] . ') ' : '';
            $trace_info .= isset($t['class']) ? $t['class'] . $t['type'] : '';
            $trace_info .= $t['function'] . '(';
            $trace_info .= empty($t['args']) ? '' : $t['args'];//str_replace(EOL_LF, ' ', stripslashes(var_export($t['args'], true)));
            $trace_info .= ")\n";
        }

        $trace_info = preg_replace('/ +/', ' ', $trace_info);
        $error['message'] = $this->message;
        $error['type'] = $this->type;
        $error['detail'] = L('_MODULE_') . '[' . MODULE_NAME . '] ' . L('_ACTION_') . '[' . ACTION_NAME . ']' . "\n";
        $error['detail'] .= ($this->line - 2) . ': ' . $file[$this->line - 3];;
        $error['detail'] .= ($this->line - 1) . ': ' . $file[$this->line - 2];
        $error['detail'] .= $this->line . ': <strong style="color: #f60;">' . $file[$this->line - 1] . '</strong>' . "\n";
        $error['detail'] .= ($this->line + 1) . ': ' . $file[$this->line];
        $error['detail'] .= ($this->line + 2) . ': ' . $file[$this->line + 1];
        //$error['class'] = $this->class;
        $error['function'] = $this->function;
        $error['file'] = $this->file;
        $error['line'] = $this->line;
        $error['trace'] = $trace_info;

        return $error;
    }
}